import { app, session } from 'electron';
import { join } from 'path';
import { BoltronConfig, WindowOptions, IpcHandler, BoltronPlugin } from '../types';
import { BoltronWindow } from './BoltronWindow';
import { IpcManager } from './IpcManager';

/**
 * Boltron 主应用程序类
 */
export class BoltronApplication {
  /**
   * 应用配置
   */
  private config: BoltronConfig;
  
  /**
   * 窗口管理映射
   */
  private windows: Map<string, BoltronWindow> = new Map();
  
  /**
   * IPC 管理器
   */
  private ipcManager: IpcManager;
  
  /**
   * 默认安全配置
   */
  private static DEFAULT_SECURITY_CONFIG = {
    contentSecurityPolicy: "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'",
    sandbox: true,
    contextIsolation: true,
  };

  /**
   * 创建 Boltron 应用程序
   * @param config 应用配置
   */
  constructor(config: BoltronConfig = {}) {
    this.config = this.mergeDefaultConfig(config);
    
    // 初始化 IPC 管理器
    this.ipcManager = new IpcManager();
    
    // 初始化应用
    this.initialize();
  }

  /**
   * 合并默认配置
   * @param config 用户提供的配置
   */
  private mergeDefaultConfig(config: BoltronConfig): BoltronConfig {
    return {
      ...config,
      security: {
        ...BoltronApplication.DEFAULT_SECURITY_CONFIG,
        ...config.security,
      },
    };
  }

  /**
   * 初始化应用
   */
  private initialize(): void {
    // 等待 Electron 应用就绪
    if (app.isReady()) {
      this.onReady();
    } else {
      app.on('ready', this.onReady.bind(this));
    }
    
    // 处理窗口全部关闭事件
    app.on('window-all-closed', () => {
      // 在 macOS 上，除非用户使用 Cmd + Q 明确退出
      // 否则保持应用活跃状态
      if (process.platform !== 'darwin') {
        app.quit();
      }
    });
    
    // macOS 应用重新激活处理
    app.on('activate', () => {
      // 在 macOS 上，当点击 dock 图标且没有其他窗口打开时，
      // 通常会在应用程序中重新创建一个窗口
      if (this.windows.size === 0) {
        // 此处不自动创建窗口，由开发者决定
      }
    });
  }

  /**
   * 应用就绪时的处理
   */
  private onReady(): void {
    // 应用安全增强配置
    this.applySecuritySettings();
  }

  /**
   * 应用安全设置
   */
  private applySecuritySettings(): void {
    const { security } = this.config;
    
    // 设置内容安全策略
    if (security?.contentSecurityPolicy) {
      session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
        callback({
          responseHeaders: {
            ...details.responseHeaders,
            'Content-Security-Policy': [security.contentSecurityPolicy!],
          },
        });
      });
    }
    
    // 其他安全设置在 BrowserWindow 创建时应用
  }

  /**
   * 创建窗口
   * @param name 窗口名称
   * @param options 窗口选项
   * @returns 创建的窗口实例
   */
  public createWindow(name: string, options: WindowOptions): BoltronWindow | Promise<BoltronWindow> {
    if (this.windows.has(name)) {
      console.warn(`窗口 "${name}" 已存在，将被覆盖`);
    }
    
    // 确保应用程序已准备就绪
    if (!app.isReady()) {
      console.warn('尝试在应用准备就绪前创建窗口，将等待应用就绪');
      
      return new Promise<BoltronWindow>(resolve => {
        const createWindowWhenReady = () => {
          const window = new BoltronWindow(name, options);
          this.windows.set(name, window);
          
          // 窗口关闭时从管理器中移除
          const nativeWindow = window.getNativeWindow();
          nativeWindow.on('closed', () => {
            this.windows.delete(name);
          });
          
          resolve(window);
        };
        
        if (app.isReady()) {
          createWindowWhenReady();
        } else {
          app.once('ready', createWindowWhenReady);
        }
      });
    }
    
    // 创建窗口
    const window = new BoltronWindow(name, options);
    
    // 存储窗口引用
    this.windows.set(name, window);
    
    // 窗口关闭时从管理器中移除
    const nativeWindow = window.getNativeWindow();
    nativeWindow.on('closed', () => {
      this.windows.delete(name);
    });
    
    return window;
  }

  /**
   * 获取窗口
   * @param name 窗口名称
   */
  public getWindow(name: string): BoltronWindow | undefined {
    return this.windows.get(name);
  }

  /**
   * 获取所有窗口
   */
  public getAllWindows(): BoltronWindow[] {
    return Array.from(this.windows.values());
  }

  /**
   * 注册 IPC 处理器
   * @param namespace 命名空间
   * @param handler 处理器对象
   */
  public registerIpcHandler(namespace: string, handler: IpcHandler): void {
    this.ipcManager.registerHandler(namespace, handler);
  }

  /**
   * 移除 IPC 处理器
   * @param namespace 命名空间
   */
  public removeIpcHandler(namespace: string): void {
    this.ipcManager.removeHandler(namespace);
  }
  
  /**
   * 获取 IPC 处理器
   * @param namespace 命名空间
   * @returns 处理器对象或 undefined
   */
  public getIpcHandler(namespace: string): IpcHandler | undefined {
    return this.ipcManager.getHandler(namespace);
  }

  /**
   * 使用插件
   * @param plugin 插件实例
   */
  public async use(plugin: BoltronPlugin): Promise<void> {
    console.log(`正在加载插件: ${plugin.name}`);
    
    try {
      // 初始化插件
      await plugin.init(this);
      console.log(`插件 ${plugin.name} 加载成功`);
    } catch (error) {
      console.error(`插件 ${plugin.name} 加载失败:`, error);
    }
  }
} 